/*********************************************************************************
 *      Copyright:  (C) 2022 Li Yanting<liyanting2@163.com>
 *                  All rights reserved.
 *
 *       Filename:  client_sqlite.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(04/19/2022)
 *         Author:  Li Yanting <liyanting2@163.com>
 *      ChangeLog:  1, Release initial version on "04/19/2022 12:47:46 PM"
 *                 
 ********************************************************************************/

#include "client_sqlite.h"

/*********************************************************************************
 *      function name:  create_database
 *        Description:  Create a database.
 *       return value:  On error, -1 is returned. On success, 0 is returned.
 *          parameter:  Address of db.
 ********************************************************************************/
int open_database(sqlite3 **db)
{
    char           *zerrmsg = 0;
    int             rv;

    rv = sqlite3_open("data.db", db);
    if(rv != SQLITE_OK )
    {
		dbg_printf("open database: %s.\n", zerrmsg);
		log_error("open database: %s.\n", zerrmsg);
		return -1;
    }
	dbg_printf("open database successfully.\n");
	log_info("open database successfully.\n");

	return 0;
}

/*********************************************************************************
 *      function name:  create_statement
 *        Description:  create a statement.
 *       return value:  On error, -1 is returned. On success, 0 is returned.
 *          parameter:  db; statement name.
 ********************************************************************************/
int create_statement(sqlite3 *db, char *statement_name)
{
    char       buffer[256];
    char       *zerrmsg = 0;
	char       *a = "(HOST INT NOT NULL, TIME CHAR(50) NOT NULL, TEMPER FLOAT NOT NULL);";
	int        rv;

	sprintf(buffer, "CREATE TABLE %s %s", statement_name, a);
	
    rv = sqlite3_exec(db, buffer, 0, 0, &zerrmsg);
    if ( rv != SQLITE_OK )
    {
		dbg_printf("create_statement: %s.\n", zerrmsg);
		log_error("create_statement: %s.\n", zerrmsg);
        return -1;
    }
	dbg_printf("create statement[%s] successfully.\n", statement_name);
	log_info("create statement[%s] successfully.\n", statement_name);

	return 0;
}

/*********************************************************************************
 *      function name:  sql_insert
 *        Description:  insert data to statement
 *       return value:  On error, -1 is returned. On success, 0 is returned.
 *          parameter:  db; statement name; current format time; temper.
 ********************************************************************************/
int sql_insert(sqlite3 *db, char *statement_name, char *format_time, float temper)
{
    char        buffer[128];
    char       *insert_err;

    sprintf(buffer, "INSERT INTO %s VALUES ('%s', '%s', '%f')", statement_name, statement_name, format_time, temper);

    if( sqlite3_exec(db, buffer, 0, 0, &insert_err) != SQLITE_OK )
    {
		dbg_printf("insert data to %s failure: %s\n", statement_name, insert_err);
        return -1;
    }
	dbg_printf("insert data[%s %s %f] to %s successful\n", statement_name, format_time, temper, statement_name);

    return 0;
}

/***************************************************************************************************
 *      function name:  sql_check
 *        Description:  Check whether there is data in the statement.
 *       return value:  Non-exist, 0 is returned. Exist, 1 is returned. On error, -1 is returned.
 *          parameter:  db; statement name;
 ***************************************************************************************************/
int sql_check(sqlite3 *db, char *statement_name)
{
	char 		 sql_cmd[64];
	char 		*check_err = NULL;
	char       **dbResult;
	int          nRow = 0;
	int          nColumn = 0;

	sprintf(sql_cmd, "SELECT * FROM %s limit 1;", statement_name);

	if( sqlite3_get_table(db, sql_cmd, &dbResult, &nRow, &nColumn, &check_err) != SQLITE_OK ) 
	{
		dbg_printf("sqlite3_get_table failure.\n");
		sqlite3_free_table(dbResult);
		return -1;
	}
	sqlite3_free_table(dbResult);

	if(  0 == nRow )
		return -1;
	else
		return 0;
}

/*********************************************************************************
 *      function name:  sql_delete
 *        Description:  Delete data in the first row.
 *       return value:  On error, -1 is returned. On success, 0 is returned.
 *          parameter:  db; statement name;
 *********************************************************************************/
int sql_delete(sqlite3 *db, char *statement_name)
{
	char        sql_cmd[64];
	char       *delete_err;

	sprintf(sql_cmd, "DELETE from %s limit 1;", statement_name);

	if( sqlite3_exec(db, sql_cmd, 0, 0, &delete_err) != SQLITE_OK )
	{
		dbg_printf("delete sended data failure.\n");
		return -1;
	}
	dbg_printf("delete sended data sucessfully.\n");
	return 0;
}

/***************************************************************************************************
 *      function name:  sql_write_to_server
 *        Description:  Send data from database to server.
 *       return value:  On error, -1 is returned. On success, size of data is returned.
 *          parameter:  db; statement name;
 ***************************************************************************************************/
int sql_write_to_server(sqlite3 *db, int sockfd, char *statement_name)
{
	char        *write_err;
	char         sql_cmd[128];
	int          fd = sockfd;

	sprintf(sql_cmd, "SELECT * FROM %s limit 1;", statement_name);
	
	if( sqlite3_exec(db, sql_cmd, callback_write, (void *)&fd, &write_err) != SQLITE_OK )
	{
		return -1;
	}
	return fd;
}

/*********************************************************************************
 *      function name:  callback_write
 *        Description:  call back of sql_write_to_server.
 *       return value:  Data.
 *          parameter:  data.
 ********************************************************************************/
static int callback_write(void *data, int argc, char **argv, char **azColName)
{
	char        buffer[128];
	int         fd = *(int *)data;
	int         rv;
	
	memset(buffer, 0, sizeof(buffer));

	sprintf(buffer, "%s | %s | %s", argv[0], argv[1], argv[2]);

	rv = write(fd, buffer, strlen(buffer));
	if( rv < 0 )
	{
		*(int *)data = -1;
	}
	*(int *)data = rv;

	return 0;
}
